#ifndef __losor_token_h__
#define __losor_token_h__

#include <inttype.h>
#include "obj_life.h"
#include "preprocessor.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum _token_type
{
    KEYWORD,
    IDENTIFIER,
    CHARACTER,
    STRING,
    COMMENT,
    INTEGER,
    FLOATING,
    OPERATOR,

    PCT_COMMA = 1 << 16,
    PCT_ASSIGN,
    PCT_ASSIGN_MUL,
    PCT_ASSIGN_DEV,
    PCT_ASSIGN_MOD,
    PCT_ASSIGN_ADD,
    PCT_ASSIGN_SUB,
    PCT_ASSIGN_SHIFT_L,
    PCT_ASSIGN_SHIFT_R,
    PCT_ASSIGN_AND,
    PCT_ASSIGN_XOR,
    PCT_ASSIGN_OR,
    PCT_CONDITION,
    PCT_LOGICAL_OR,
    PCT_LOGICAL_AND,
    PCT_INCLUSIVE_OR,
    PCT_EXCLUSIVE_OR,
    PCT_AND,
    PCT_EQUAL,
    PCT_UNEQUAL,
    PCT_SMALL,
    PCT_LARGE,
    PCT_SMALL_EQUAL,
    PCT_LARGE_EQUAL,
    PCT_SHIFT_L,
    PCT_SHIFT_R,
    PCT_ADD,
    PCT_SUB,
    PCT_MUL,
    PCT_DEV,
    PCT_MOD,
    PCT_CAST,
    PCT_ADDRESS,
    PCT_VALUE,
    PCT_POSITIVE,
    PCT_NEGATIVE,
    PCT_NOT,
    PCT_LOGICAL_NOT,
    PCT_SIZEOF,
    PCT_ARRAY_L,
    PCT_ARRAY_R,
    PCT_CALL,
    PCT_DOT,
    PCT_POINT,
    PCT_INC_PRE,
    PCT_INC_POST,
    PCT_DEC_PRE,
    PCT_DEC_POST,
    PCT_PARENTHESES_L,
    PCT_PARENTHESES_R,

    KW_AUTO,
    KW_BREAK,
    KW_CASE,
    KW_CHAR,
    KW_CONST,
    KW_CONTINUE,
    KW_DEFAULT,
    KW_DO,
    KW_DOUBLE,
    KW_ELSE,
    KW_ENUM,
    KW_EXTERN,
    KW_FLOAT,
    KW_FOR,
    KW_GOTO,
    KW_IF,
    KW_INLINE,
    KW_INT,
    KW_LONG,
    KW_REGISTER,
    KW_RESTRICT,
    KW_RETURN,
    KW_SHORT,
    KW_SIGNED,
    KW_SIZEOF,
    KW_STATIC,
    KW_STRUCT,
    KW_SWITCH,
    KW_TYPEDEF,
    KW_UNION,
    KW_UNSIGNED,
    KW_VOID,
    KW_VOLATILE,
    KW_WHILE,
    KW_BOOL,
    KW_COMPLEX,
    KW_IMAGINARY,

} token_type;

typedef struct _token
{
    control_life();
    struct _exp_tree *ppcond;
    int type;
    void* attr;
    char *name;
    const char *file;
    int32 line;
} token;

typedef struct _opt_attr
{
    int is_ambiguity;
    int priorty;
    void *lex_func;
    void *calc_func;
    void *assemble_func;
} opt_attr;

#define TOKEN_TYPE(toke)        (toke->type & 0xffff)
#define PCT_TYPE(toke)          (TOKEN_TYPE(toke)==OPERATOR ? (toke->type & 0xffff0000) : 0)
#define KW_TYPE(toke)           (TOKEN_TYPE(toke)==KEYWORD ? (toke->type & 0xffff0000) : 0)

token* token_create( int type, code *cd, uint8 *end, void *attr, struct _exp_tree *ppcond );
token* token_create_raw( int type, const char *name, char *file, int line, void *attr, struct _exp_tree *ppcond );
int token_release( token *tk );
int tkcmp( token *t1, token *t2 );

#ifdef __cplusplus
};
#endif

#endif // __losor_token_h__
